
//
//  WBStatusListViewModel.swift
//  GitWeibo
//
//  Created by 胡金东 on 2017/5/27.
//  Copyright © 2017年 胡金东. All rights reserved.
//

import Foundation
import SDWebImage

/*
 父类的选择
 
 - 如果类需要使用 `KVC` 或者字典转模型框架设置对象值，类就需要继承自 NSObject
 - 如果类只是包装一些代码逻辑(写了一些函数)，可以不用任何父类，好处：更加轻量级
 - 提示：如果用 OC 写，一律都继承自 NSObject 即可
 
 使命：负责微博的数据处理
 1. 字典转模型
 2. 下拉／上拉刷新数据处理
 */

let maxPullupTryTimes = 3


class WBStatusListViewModel{
    

    /// - 微博模型数组懒加载
    lazy var statusList = [WBStatusViewModel]()
    var pullupErrorTimes = 0

    
    /// 刷新微博列表
    ///
    /// - Parameters:
    ///   - isPull: 是否上拉刷新标记
    ///   - completion: 完成回调[网络请求是否成功，是否刷新表格]
    func loadStatus(isPull:Bool ,completion:@escaping (_ isSuccess:Bool,_ shouldRefresh:Bool) -> ()) {
        
        if isPull && pullupErrorTimes > maxPullupTryTimes {
            completion(true, false)
            return
        }
        
        /// - 下拉刷新
        /// - 取出新数组中第一条数据 id ，如果没有就给0
        let since_id = isPull ? 0 : (statusList.first?.status.id ?? 0)
        /// - 上拉刷新
        let max_id = !isPull ?  0 : (statusList.last?.status.id ?? 0)
        
        WBNetWorkSessionManager.NetWorkshared().statusList(since_id: since_id ,max_id: max_id) { (list, isSuccess) in
            
            /// - 0 判断网络请求是否成功
            if !isSuccess {
                /// - 直接回调返回
                completion(false, false)
                return
            }
            /// - 1.字典转模型
            /// - 1> 定义结果可变数组
            var array = [WBStatusViewModel]()
            /// - 2> 遍历服务器返回的字典数组，字典转模型
            /// - Option + cmd + 左 折叠代码
            for dict in list ?? [] {
                
//                  print(dict["pic_urls"])
//                /// - 创建微博模型 - 如果模型失败，继续后续遍历
//                guard let model = WBStatusModel.yy_model(with: dict) else {
//                    continue
//                }
//                /// - 将视图模型 添加到数组
//                array.append(WBStatusViewModel(model: model))
//                
                
                /// - 创建微博模型
                let status = WBStatusModel()
                /// - 使用字典设置模型数值
                status.yy_modelSet(with: dict)
                /// - 使用 “微博” 模型创建 “微博视图” 模型
                let viewModel = WBStatusViewModel(model: status)
                
                ///  添加到数组
                array.append(viewModel)

            }
    
                        print("\(array)")
            
            
            // 2. 拼接数据
            if isPull {
                // 上拉刷新结束后，将结果拼接在数组的末尾
                self.statusList += array
            } else {
                // 下拉刷新，应该将结果数组拼接在数组前面
                self.statusList = array + self.statusList
            }
            
            if isPull && array.count == 0 {
                self.pullupErrorTimes += 1
                
                completion(isSuccess, false)

            }else{
                self.cacheSingleImage(list: array,finsh:completion)
//                /// - 3 完成回调
//                completion(isSuccess,true)
            }
    
            
            print("刷新到\(array.count)数据")
        }
    }
    
    func cacheSingleImage(list: [WBStatusViewModel],finsh:@escaping (_ isSuccess:Bool,_ shouldRefresh:Bool) -> ())  {
        
        /// - 调度组
        let group = DispatchGroup()
        // 记录数据长度
        var length = 0
        /// - 遍历数组，查找微博数据中有单张图像的，进行缓存
        for vm in list {
            
       
            /// - 判断图像的数量
            if vm.picURLs?.count != 1 {
                /// - 不等于1 就直接走上面
                continue
            }
            /// - 代码执行到此，数组中仅有一张图片
            guard let pic = vm.picURLs?[0].thumbnail_pic,
                let url = URL(string: pic) else {
                    continue
            }
            /// - 1.入组
            group.enter()
            
            SDWebImageManager.shared().loadImage(with: url, options: [], progress: nil, completed: { (image, _, _, _, _, _) in
                /// - 将图像转换成二进制数据
                if let image = image ,
                    let data = UIImagePNGRepresentation(image){
                    
                    /// - NSData 是 length 属性
                    length += data.count
                    /// - 图像缓存成功 ，更新配图视图的大小
                    vm.updateSingImageSize(image: image)
                }
                print("图像的大小\(length)")
                /// - 2.出组
                group.leave()
            })
            
        }
        
        /// - 3. 监听调度组情况
        group.notify(queue: DispatchQueue.main){
            print("图像缓存完成\(length/1024)K")
            
            /// - 执行闭包回调
            /// - true 只有成功才能缓存数据
            finsh(true, true)
        }
        /**
         上面是Swift写法
         
         有时候我们会有这样的需求：分别异步执行2个耗时操作，然后当2个耗时操作都执行完毕后再回到主线程执行操作。这时候我们可以用到GCD的队列组。
         我们可以先把任务放到队列中，然后将队列放入队列组中。
         调用队列组的dispatch_group_notify回到主线程执行操作。
         dispatch_group_t group =  dispatch_group_create();
         
         dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         // 执行1个耗时的异步操作
         });
         
         dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         // 执行1个耗时的异步操作
         });
         
         dispatch_group_notify(group, dispatch_get_main_queue(), ^{
         // 等前面的异步操作都执行完毕后，回到主线程...
         });
         */
        
        
    }
    
}
